package com.langchain4j.core.flow.engine;

import com.langchain4j.core.flow.result.NodeResult;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * 流程执行结果
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FlowExecutionResult {
    
    /**
     * 执行ID
     */
    private String executionId;
    
    /**
     * 流程ID
     */
    private String flowId;
    
    /**
     * 执行状态
     */
    private ExecutionStatus status;
    
    /**
     * 输出结果
     */
    private Map<String, Object> outputs;
    
    /**
     * 节点执行结果
     */
    private Map<String, NodeResult> nodeResults;
    
    /**
     * 错误信息
     */
    private String errorMessage;
    
    /**
     * 异常对象
     */
    private Throwable error;
    
    /**
     * 开始时间
     */
    private LocalDateTime startTime;
    
    /**
     * 结束时间
     */
    private LocalDateTime endTime;
    
    /**
     * 执行耗时（毫秒）
     */
    private Long duration;
    
    /**
     * 执行状态枚举
     */
    public enum ExecutionStatus {
        RUNNING("执行中"),
        SUCCESS("成功"),
        FAILED("失败"),
        CANCELLED("取消"),
        TIMEOUT("超时");
        
        private final String description;
        
        ExecutionStatus(String description) {
            this.description = description;
        }
        
        public String getDescription() {
            return description;
        }
    }
    
    /**
     * 是否成功
     */
    public boolean isSuccess() {
        return ExecutionStatus.SUCCESS.equals(status);
    }
    
    /**
     * 是否失败
     */
    public boolean isFailed() {
        return ExecutionStatus.FAILED.equals(status);
    }
    
    /**
     * 是否正在执行
     */
    public boolean isRunning() {
        return ExecutionStatus.RUNNING.equals(status);
    }
    
    /**
     * 计算执行耗时
     */
    public Long getDuration() {
        if (duration != null) {
            return duration;
        }
        if (startTime != null && endTime != null) {
            return java.time.Duration.between(startTime, endTime).toMillis();
        }
        return null;
    }
} 